package sso.interceptor;

import io.jsonwebtoken.Claims;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.WebAuthenticationDetails;
import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken;
import org.springframework.web.servlet.HandlerInterceptor;
import sso.util.JwtUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;

public class TokenInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(
            HttpServletRequest request,
            HttpServletResponse response,
            Object handler) throws Exception {
        //1.从请求中获取token对象(传递的token的方式有header，params)
        String token = request.getHeader("token");
       // String token1 = request.getParameter("token");
        //2.验证token是否存在
        if (token == null ||"".equals(token)) {
            throw  new RuntimeException("请先登陆");
        }
        //3.验证token是否过期
        if (JwtUtils.isTokenExpired(token)) {
            throw new RuntimeException("登陆超时。请重新登陆");
        }
        //4.解析token中的认证和权限信息
        Claims clansToken = JwtUtils.getClansToken(token);
       List<String> list =(List<String>) clansToken.get("authorities");

        //5.封装和存储认证和权限信息,构建userdatail对象；
        UserDetails userDetails=User.builder()
                .username((String)clansToken.get("username"))
                .password("")
                .authorities(list.toArray(new String[]{}))
                .build();
        //构建security 权限交互权限
        PreAuthenticatedAuthenticationToken  authtoken=
                new PreAuthenticatedAuthenticationToken(
                        userDetails,
                        userDetails.getPassword(),
                        userDetails.getAuthorities()
                );

        //将权限交互对象与当前对象进行绑定
        authtoken.setDetails(new WebAuthenticationDetails(request));

        //将认证后的token存储到security会话容器
        SecurityContextHolder.getContext().setAuthentication(authtoken);
        return true;
    }
}
